package com.masonluo.mlonlinejudge.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.masonluo.mlonlinejudge.exceptions.HttpRequestFailureException;
import com.masonluo.mlonlinejudge.mapper.ResultDataMapper;
import com.masonluo.mlonlinejudge.model.dto.JudgeParamDto;
import com.masonluo.mlonlinejudge.model.judge.JudgeResult;
import com.masonluo.mlonlinejudge.service.JudgeService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author masonluo
 * @date 2021/2/5 9:38 下午
 */
@Service
public class JudgeServiceImpl implements JudgeService {

    private final RestTemplate restTemplate;

    private final String judgeServerUrl;

    private final String xJudgeServerToken;

    private final ObjectMapper objectMapper;

    private final ResultDataMapper resultDataMapper;

    public JudgeServiceImpl(RestTemplate restTemplate,
                            ObjectMapper objectMapper,
                            ResultDataMapper resultDataMapper,
                            @Value("${judge.server.url}") String judgeServerUrl,
                            @Value("${judge.server.token}") String xJudgeServerToken) {
        this.restTemplate = restTemplate;
        this.judgeServerUrl = judgeServerUrl;
        this.xJudgeServerToken = xJudgeServerToken;
        this.objectMapper = objectMapper;
        this.resultDataMapper = resultDataMapper;
    }

    @Override
    @SuppressWarnings("unchecked")
    public JudgeResult judge(JudgeParamDto judgeParamDto) throws HttpRequestFailureException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("X-JUDGE-SERVER-TOKEN", xJudgeServerToken);
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<JudgeParamDto> entity = new HttpEntity<>(judgeParamDto, headers);
        try {
            System.out.println(objectMapper.writeValueAsString(judgeParamDto));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ResponseEntity<JudgeResult> responseEntity = restTemplate.postForEntity(judgeServerUrl + "/judge", entity, JudgeResult.class);
        if (!responseEntity.getStatusCode().is2xxSuccessful()) {
            throw new HttpRequestFailureException("The judge server can't resolve the problem," +
                    " please try again, response http code [" + responseEntity.getStatusCodeValue() + "]");
        }
        JudgeResult res = responseEntity.getBody();

        System.err.println(res.toString());

        if (res == null) {
            throw new HttpRequestFailureException("The judge server response a empty result, please try again");
        }
        if (res.getErr() == null) {
            List<Map<String, Object>> data = (List<Map<String, Object>>) res.getData();
            res.setData(resultDataMapper.map(data));
        }
        List<String> list=new ArrayList<>();
        return res;
    }
}
